package com.itheima.tlais_web_management.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect //注明该类是一个切面类
@Component //标记该类成为了 spring 的一个 Bean 组件。
public class TimeAspect {

    /**
     * 1、面向切面编程是一种编程思想
     *
     * 2、动态代理是这种思想的实现方式
     *
     * 3、SpringAOP 就是基于动态代理，面向特定的方法进行编程
     *
     * 4、SpringAOP 开发步骤
     */

    /**
     * AOP
     * 1、代码无侵入
     * 2、减少重复代码
     * 3、提高开发效率
     * 4、维护方便
     * @param joinPoint
     * @return
     * @throws Throwable
     */

    /**
     * 1、JoinPoint：可以被 AOP 控制的方法：连接点 （连接点中存储的是 目标方法的信息）
     *
     * 2、Advice：重复逻辑、共性功能，体现为一个方法：通知
     *
     * 3、PointCut：匹配连接点：切入点 （execution：切点表达式（方法信息））（annotation:切点表达式（注解全类名））
     *
     * 4、Aspect：通知 + 切入点 = 切面
     *
     * 5、Target：通知所应用的对象：目标对象
     * @param joinPoint
     * @return
     * @throws Throwable
     */

        @Around("execution(* com.itheima.tlais_web_management.service.*.*(..))")//切入点表达式
        public Object begin(ProceedingJoinPoint joinPoint) throws Throwable {
            //额外提供了一个非常重要的方法 proceed()，这个方法允许调用者决定是否继续执行被拦截的方法，并且可以控制其执行流程，比如在调用前后添加额外的操作。

            /**
             *
             * Around 只能用 ProceedingJoinPoint
             *
             */

            // 开始时间
               long begin = System.currentTimeMillis();

               //原始方法
                Object result = joinPoint.proceed();

                // 结束时间
                long end = System.currentTimeMillis();

                log.info("方法耗时：" + (end - begin) + "ms");
                System.out.println(joinPoint.getSignature() + "方法耗时：" + (end - begin) + "ms");

                return result;
        }


}
